package com.lxk.oms.cart.api;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lxk.oms.cart.domain.OmsCart;
import com.lxk.oms.cart.mapper.OmsCartMapper;
import com.lxk.service.cart.api.CartServiceApi;
import com.lxk.service.cart.param.CartAddParam;
import com.lxk.service.cart.param.CartResetParam;
import com.lxk.service.cart.param.CartUpdateParam;
import com.lxk.service.cart.param.CartUpdateSelectParam;
import com.lxk.service.cart.response.CartListRespVo;
import com.lxk.service.core.Result;
import com.lxk.service.core.enums.SpuStatusEnum;
import com.lxk.service.pms.api.PmsServiceApi;
import com.lxk.service.pms.request.CheckSkuStockParam;
import com.lxk.service.pms.response.PmsProductSkuDto;
import com.lxk.service.pms.response.PmsProductSpuDto;
import com.lxk.service.pms.response.SkuCheckStockItemResult;
import lombok.AllArgsConstructor;
import org.dromara.common.core.utils.ValidationUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.lxk.service.core.enums.ErrorCodeConstants.CARD_ITEM_NOT_FOUND;
import static com.lxk.service.core.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
import static java.util.Collections.emptyList;

/**
 * 购物车 Service 实现类
 *
 * @author huahua
 */
@Service
@AllArgsConstructor
public class CartServiceImpl implements CartServiceApi {

    private final OmsCartMapper cartMapper;
    private final PmsServiceApi pmsServiceApi;

    @Override
    public Result<Long> addCart(Long userId, CartAddParam param) {
        ValidationUtils.validate(param);
        // 查询
        OmsCart cart = cartMapper.selectOne(new LambdaQueryWrapper<OmsCart>().eq(OmsCart::getSkuId, param.getSkuId()).eq(OmsCart::getUserId, userId));
        // 校验 SKU
        Integer count = param.getCount();
        CheckSkuStockParam checkSkuStockParam = new CheckSkuStockParam();
        checkSkuStockParam.setSkuId(param.getSkuId());
        checkSkuStockParam.setNum(count);
        checkSkuStockParam.setMerId(param.getMerId());
        Result<SkuCheckStockItemResult> sku = pmsServiceApi.checkStockBySkuId(checkSkuStockParam);
        if (sku.isSuccess() && !sku.getData().getResult()) {
            Result.fail(sku.getData().getMessage());
        }
        // 情况一：存在，则进行数量更新
        if (cart != null) {
            OmsCart omsCart = new OmsCart();
            omsCart.setId(cart.getId());
            omsCart.setSelected(true);
            omsCart.setCount(cart.getCount() + count);
            cartMapper.updateById(omsCart);
            return Result.ok(omsCart.getId());
            // 情况二：不存在，则进行插入
        } else {
            Result<PmsProductSkuDto> result = pmsServiceApi.queryBySkuId(param.getSkuId());
            if (result == null || result.getData() == null) {
                return Result.fail(SKU_NOT_EXISTS.getMsg());
            }
            PmsProductSkuDto dto = result.getData();
            OmsCart omsCart = new OmsCart();
            omsCart.setMerId(param.getMerId());
            omsCart.setUserId(userId);
            omsCart.setSelected(true);
            omsCart.setSpuId(dto.getSpuId());
            omsCart.setSkuId(dto.getId());
            omsCart.setCount(count);
            cartMapper.insert(omsCart);
            return Result.ok(omsCart.getId());
        }
    }

    @Override
    public Result<Boolean> updateCartCount(Long userId, CartUpdateParam param) {
        ValidationUtils.validate(param);
        // 查询
        OmsCart cart = cartMapper.selectOne(new LambdaQueryWrapper<OmsCart>().eq(OmsCart::getId, param.getId()).eq(OmsCart::getUserId, userId));
        if (cart == null) {
            return Result.fail(CARD_ITEM_NOT_FOUND.getMsg());
        }
        // 校验商品 SKU
        // 校验 SKU
        CheckSkuStockParam checkSkuStockParam = new CheckSkuStockParam();
        checkSkuStockParam.setSkuId(cart.getSkuId());
        checkSkuStockParam.setNum(param.getCount());
        checkSkuStockParam.setMerId(cart.getMerId());
        Result<SkuCheckStockItemResult> sku = pmsServiceApi.checkStockBySkuId(checkSkuStockParam);
        if (sku.isSuccess() && !sku.getData().getResult()) {
            Result.fail(sku.getData().getMessage());
        }
        OmsCart omsCart = new OmsCart();
        omsCart.setId(cart.getId());
        omsCart.setMerId(cart.getMerId());
        omsCart.setCount(param.getCount());
        // 更新数量
        return Result.ok(cartMapper.updateById(omsCart) > 0);
    }

    @Override
    public Result<Boolean> updateCartSelected(Long userId, CartUpdateSelectParam param) {
        ValidationUtils.validate(param);
        OmsCart omsCart = new OmsCart();
        omsCart.setSelected(param.getSelected());
        cartMapper.update(omsCart, new LambdaQueryWrapper<OmsCart>().in(OmsCart::getId, param.getIds()).eq(OmsCart::getUserId, userId));
        return Result.ok(true);
    }

    @Override
    @DSTransactional(rollbackFor = Exception.class)
    public Result<Boolean> resetCart(Long userId, CartResetParam param) {
        // 第一步：删除原本的购物项
        OmsCart oldCart = cartMapper.selectOne(new LambdaQueryWrapper<OmsCart>().eq(OmsCart::getId, param.getId()).eq(OmsCart::getUserId, userId));
        if (oldCart == null) {
            return Result.fail(CARD_ITEM_NOT_FOUND.getMsg());
        }
        cartMapper.deleteById(oldCart.getId());

        // 第二步：添加新的购物项
        OmsCart newCart = cartMapper.selectOne(new LambdaQueryWrapper<OmsCart>().eq(OmsCart::getSkuId, param.getSkuId()).eq(OmsCart::getUserId, userId));
        if (newCart != null) {
            CartUpdateParam update = new CartUpdateParam();
            update.setId(newCart.getId());
            update.setCount(param.getCount());
            return updateCartCount(userId, update);
        } else {
            CartAddParam addParam = new CartAddParam();
            addParam.setMerId(param.getMerId());
            addParam.setSkuId(param.getSkuId());
            addParam.setCount(param.getCount());
            Result<Long> result = addCart(userId, addParam);
            return Result.ok(result.isSuccess());
        }
    }

    /**
     * 购物车删除商品
     *
     * @param userId 用户编号
     * @param ids    商品 SKU 编号的数组
     */
    @Override
    public Result<Boolean> deleteCart(Long userId, Collection<Long> ids) {
        // 查询 TradeCartDO 列表
        List<OmsCart> carts = cartMapper.selectList(new LambdaQueryWrapper<OmsCart>().in(OmsCart::getId, ids).eq(OmsCart::getUserId, userId));
        if (CollUtil.isEmpty(carts)) {
            return Result.ok(true);
        }

        // 批量标记删除
        cartMapper.deleteBatchIds(ids);
        return Result.ok(true);
    }

    @Override
    public Result<Long> getCartCount(Long userId) {
        return Result.ok(cartMapper.selectSumByUserId(userId));
    }

    @Override
    public Result<CartListRespVo> getCartList(Long userId) {
        List<OmsCart> carts = cartMapper.selectList(new LambdaQueryWrapper<OmsCart>().eq(OmsCart::getUserId, userId));
        carts.sort(Comparator.comparing(OmsCart::getId).reversed());
        // 如果未空，则返回空结果
        if (CollUtil.isEmpty(carts)) {
            CartListRespVo respVo = new CartListRespVo();
            respVo.setInvalidList(emptyList());
            respVo.setValidList(emptyList());
            return Result.ok(respVo);
        }

        // 查询 SPU、SKU 列表
        List<Long> spuIds = carts.stream().map(OmsCart::getSpuId).distinct().collect(Collectors.toList());
        Result<List<PmsProductSpuDto>> spusResult = pmsServiceApi.queryBySpuIdList(spuIds, false);
        List<PmsProductSpuDto> spus = spusResult.getData();
        List<Long> skuIds = carts.stream().map(OmsCart::getSkuId).distinct().collect(Collectors.toList());
        Result<List<PmsProductSkuDto>> skusResult = pmsServiceApi.queryBySkuIdList(skuIds);
        List<PmsProductSkuDto> skus = skusResult.getData();

        // 如果 SPU 被删除，则删除购物车对应的商品。延迟删除
        // 为什么不是 SKU 被删除呢？因为 SKU 被删除时，还可以通过 SPU 选择其它 SKU
        deleteCartIfSpuDeleted(carts, spus);

        return Result.ok(convertList(carts, spus, skus));
    }

    private void deleteCartIfSpuDeleted(List<OmsCart> carts, List<PmsProductSpuDto> spus) {
        // 如果 SPU 被删除，则删除购物车对应的商品。延迟删除
        carts.removeIf(cart -> {
            if (spus.stream().noneMatch(spu -> spu.getId().equals(cart.getSpuId()))) {
                cartMapper.deleteById(cart.getId());
                return true;
            }
            return false;
        });
    }

    private CartListRespVo convertList(List<OmsCart> carts, List<PmsProductSpuDto> spus, List<PmsProductSkuDto> skus) {
        CartListRespVo cartListRespVo = new CartListRespVo();
        Map<Long, PmsProductSpuDto> spuMap = spus.stream().collect(Collectors.toMap(PmsProductSpuDto::getId, Function.identity()));
        Map<Long, PmsProductSkuDto> skuMap = skus.stream().collect(Collectors.toMap(PmsProductSkuDto::getId, Function.identity()));
        // 遍历，开始转换
        List<CartListRespVo.Cart> validList = new ArrayList<>(carts.size());
        List<CartListRespVo.Cart> invalidList = new ArrayList<>();
        carts.forEach(cart -> {
            CartListRespVo.Cart cartVO = new CartListRespVo.Cart();
            cartVO.setId(cart.getId());
            cartVO.setCount(cart.getCount());
            cartVO.setSelected(cart.getSelected());
            cartVO.setSpuId(cart.getSpuId());
            cartVO.setSkuId(cart.getSkuId());
            PmsProductSpuDto spu = spuMap.get(cart.getSpuId());
            PmsProductSkuDto sku = skuMap.get(cart.getSkuId());
            if (spu != null) {
                cartVO.setDescription(spu.getDescription());
                cartVO.setName(spu.getName());
            }
            if (sku != null) {
                cartVO.setPrice(sku.getPrice());
                cartVO.setImage(sku.getPicUrl());
            }
            // 如果 SPU 不存在，或者下架，或者库存不足，说明是无效的
            if (spu == null
                || !SpuStatusEnum.isEnable(spu.getStatus())
                || spu.getStock() <= 0) {
                cartVO.setSelected(false); // 强制设置成不可选中
                invalidList.add(cartVO);
            } else {
                // 虽然 SKU 可能也会不存在，但是可以通过购物车重新选择
                validList.add(cartVO);
            }
        });
        cartListRespVo.setValidList(validList);
        cartListRespVo.setInvalidList(invalidList);
        return cartListRespVo;
    }
}
